<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>

  <div>参考地址：https://juejin.cn/post/6978728619782701087#heading-3</div>

</body>
<script>
  class PubSub {
    constructor() {
      this.messages = {};
      this.listens = {}
    }
    // 订阅
    subscribe(type, cb) {
      if (!this.listens[type]) {
        this.listens[type] = [cb]
      } else {
        this.listens[type].push(cb)
      }

    }
    //发布
    publish(type, message) {
      if (!this.messages[type]) {
        this.messages[type] = [message]
      } else {
        this.messages[type].push(message)
      }
    }
    //通知
    notify(type) {
      // 这里只实现一个通知功能，实际需求，可以随时改
      const messages = this.messages[type] || [];
      const subscribes = this.listens[type] || [];
      subscribes.forEach((cb, index) => cb(messages[index]))

    }
  }

  class Publisher {
    constructor(name, context) {
      this.name = name;
      this.context = context;
    }
    publish(type, message) {
      this.context.publish(type, message)
    }
  }

  class Subscribe {
    constructor(name, context) {
      this.name = name;
      this.context = context
    }
    subscribe(type, cb) {
      this.context.subscribe(type, cb)
    }
  }

  const TYPE_A = 'music';
  const TYPE_B = 'movie';
  const TYPE_C = 'novel';
  const pubsub = new PubSub();
  const publisher1 = new Publisher('publisher1', pubsub)
  const publisher2 = new Publisher('publisher2', pubsub);

  publisher1.publish(TYPE_A, '你好')
  publisher2.publish(TYPE_A, '我不好')

  const subscribe1 = new Subscribe('subscribe1', pubsub);
  const subscribe2 = new Subscribe('subscribe2', pubsub);

  subscribe1.subscribe(TYPE_A, (msg) => {
    console.log(this.name + '订阅了:' + msg)
  })
  subscribe2.subscribe(TYPE_A, (msg) => {
    console.log(this.name + '订阅了:' + msg)
  })

  pubsub.notify(TYPE_A)

</script>

</html>